<?php

/***
 * Class CW_MutexClass is a static class that creates file locks for mutual exclusion. This
 * prevents one part of the system from writing to a file that is being used by another.
 ***/
class CW_MutexClass {

   // ! Executor Method

   /**
	* Checks if the specified file has already been locked. If it has,
	* then check if it has expired. If expired, return false, if not,
	* then create a new locked file.
	*
	* @param String $path Path to the locked file
	* @param String $file Full name, including extension, of the locked file
	* @param Integer $time_to_live Expiration date of the locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Mixed
	*/
	public static function processFileLock($path, $file, $time_to_live = 5)
	{
		if(false == is_dir($path))
		{
			return false;
		}

		$full_lock_path = self::getFullLockPath($path, $file);

		if(self::isFileLocked($full_lock_path))
		{
			if(self::isLockExpired($full_lock_path))
			{
				return false;
			}
		}

		return self::lockFile($full_lock_path);
	}


   // ! Executor Method

   /**
	* Returns a nicely formatted path of the locked file.
	*
	* @param String $path Path to the locked file
	* @param String $file Full name, including extension, of the locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	public static function getFullLockPath($path, $file)
	{
		return preg_replace('#[/|\\\]+$#', '', $path) . DIRECTORY_SEPARATOR . self::getLockId($name) . '.lock';
	}


   // ! Accessor Method

   /**
	* Checks against the file's creation timestamp to determine
	* whether or not it has expired.
	*
	* @param String $file Path to the locked file
	* @param Integer $time_to_live Expiration date of the locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	public static function isLockExpired($file, $time_to_live = 5)
	{
		if((time() - filectime($file)) >= $time_to_live)
		{
			return true;
		}

		return false;
	}


   // ! Executor Method

   /**
	* Creates a locked file.
	*
	* @param String $path Full path to locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Mixec
	*/
	public static function lockFile($path)
	{
		return file_put_contents($path, 'LOCKED FILE');
	}


   // ! Executor Method

   /**
	* Removes a specified locked file.
	*
	* @param String $path Full path to locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Mixed
	*/
	public static function unlockFile($path)
	{
		return @unlink($path);
	}


   // ! Accessor Method

   /**
	* Checks if a locked file exists.
	*
	* @param String $path Full path to locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	public static function isFileLocked($path)
	{
		return file_exists($path);
	}


   // ! Executor Method

   /**
	* Creates a hash of the file name for obscurity.
	*
	* @param String $file Name of the locked file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return String
	*/
	private static function getLockId($file)
	{
		return md5($file);
	}
}

?>